package com.mdp.workflow.biz.re.ctrl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.entity.Result;
import com.mdp.core.err.BizException;
import com.mdp.core.query.QueryTools;
import com.mdp.core.utils.ObjectTools;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.mdp.swagger.ApiEntityParams;
import com.mdp.workflow.api.FlowModelService;
import com.mdp.workflow.biz.re.entity.Model;
import com.mdp.workflow.biz.re.mapper.ModelMapper;
import com.mdp.workflow.biz.re.service.DeploymentService;
import com.mdp.workflow.biz.re.vo.ModelVo;
import com.mdp.workflow.comm.tools.FlowModelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.RepositoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value="/*/re/model")
@Api(tags={"act_de_model-操作接口"})
public class ModelController {

	static Logger logger =LoggerFactory.getLogger(ModelController.class);

	@Autowired
	private FlowModelService modelService;

	@Autowired
	private DeploymentService deploymentService;

	@Autowired
	ModelMapper modelMapper;

	@Value(value = "${mdp.platform-branch-id:platform-branch-001}")
	String platformBranchId;

	@ApiOperation( value = "act_de_model-查询列表",notes=" ")
	@ApiEntityParams(Model.class)
	@ApiResponses({
		@ApiResponse(code = 200,response= Model.class,message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'错误码'},total:总记录数,data:[数据对象1,数据对象2,...]}")
	})
	@RequestMapping(value="/list",method=RequestMethod.GET)
	public Result listModel(@ApiIgnore @RequestParam Map<String,Object> params){

			User user=LoginUtils.getCurrentUserInfo();
			QueryWrapper<Model> qw = QueryTools.initQueryWrapper(Model.class , params)
					.in("tenant_id_",platformBranchId,user.getBranchId());
			IPage page=QueryTools.initPage(params);
			List<Map<String,Object>> datas = modelService.selectListMapByWhere(page,qw,params);
			return Result.ok("query-ok","查询成功").setData(datas).setTotal(page.getTotal());

	}


	@ApiOperation( value = "act_de_model-新增",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200,response= Model.class,message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	})
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public Result addModel(@RequestBody ModelVo model) {
		if(ObjectTools.isEmpty(model.getBpmnXml())){
			throw new BizException("bpmnXml-required","模型数据不能为空");
		}

		 String modelId=modelService.createModel(model);
         return Result.ok("add-ok","添加成功！").setData(modelId);
	}

	@ApiOperation( value = "act_de_model-删除",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}}")
	})
	@RequestMapping(value="/del",method=RequestMethod.POST)
	public Result delModel(@RequestBody Model model){
		User user=LoginUtils.getCurrentUserInfo();
		org.flowable.engine.repository.Model modelDb=modelService.getModel(model.getId());
		String modelBranchId=modelDb.getTenantId();
		if(!user.getBranchId().equals(modelBranchId)){
			return Result.error("tenant-id-not-platform-001","该流程属于其它机构【%s】的流程模型，你无权删除",modelBranchId);
		}
		if(LoginUtils.hasAnyRoles("flowAdmin","platformAdmin","branchAdmin")) {
			modelService.deleteModel(model.getId());
		}else{
			return Result.error("need-flowAdmin-or-platformAdmin", "该接口属于重大影响接口，需要流程管理员或者平台管理员才能操作");
		};
        return Result.ok("del-ok","删除成功！");
	}

	@ApiOperation( value = "act_de_model-修改",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200,response= Model.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	})
	@RequestMapping(value="/edit",method=RequestMethod.POST)
	public Result editModel(@RequestBody ModelVo model) {
		modelService.updateModel(model);
        return Result.ok("edit-ok","修改成功！");
	}



	@ApiOperation( value = "act_de_model-批量删除",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}")
	})
	@RequestMapping(value="/batchDel",method=RequestMethod.POST)
	public Result batchDelModel(@RequestBody List<Model> models) {
	    modelService.removeByIds(models.stream().map(k->k.getId()).collect(Collectors.toSet()));
		return Result.ok();
	}

	@ApiOperation( value = "act_de_model-根据主键查询一条数据",notes=" ")
     @ApiResponses({
            @ApiResponse(code = 200,response= Model.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
    })
    @RequestMapping(value="/queryById",method=RequestMethod.GET)
    public Result queryById(Model model) {
		Model data=modelMapper.selectById(model.getId());
		byte[] bpmnXml=modelService.getModelBpmnXML(data.getId());
		ModelVo modelVo=new ModelVo();
		modelVo.setModel(data);
		modelVo.setBpmnXml(new String(bpmnXml));
		return Result.ok().setData(modelVo);
    }

	@ApiOperation( value = "act_de_model-根据主键查询一条数据",notes=" ")
	@ApiResponses({
			@ApiResponse(code = 200,response= Model.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	})
	@RequestMapping(value="/queryByKey",method=RequestMethod.GET)
	public Result queryByKey(Model model) {
		Assert.notBlank(model.getKey(),"参数必填%s","key");
		List<Model> models=modelMapper.selectList(QueryTools.initQueryWrapper(Model.class).eq("key_",model.getKey()));

		if(models!=null && models.size()>0){
			Model data=models.get(0);
			byte[] bpmnXml=modelService.getModelBpmnXML(data.getId());
			ModelVo modelVo=new ModelVo();
			modelVo.setModel(data);
			modelVo.setBpmnXml(new String(bpmnXml));
			return Result.ok().setData(modelVo);
		}else {
			return Result.error("data-0","流程模型不存在");
		}

	}

	/**
	 * 发布流程
	 */

	@RequestMapping(value="/deploy")
	public Result deployModel(@RequestBody Model model) {
			if(LoginUtils.hasAnyRoles("superAdmin","flowAdmin","platformAdmin","branchAdmin")) {
				modelService.deployModel(model.getId());
			}else{
				return Result.error("need-flowAdmin-or-platformAdmin","该接口属于重大影响接口，需要流程管理员、平台管理员、机构管理员才能操作");
			};

			return Result.ok();
	}
	/**
	 * 发布流程
	 */

	@RequestMapping(value="/unDeploy")
	public Result unDeployModel(@RequestBody Model model) {

			User user=LoginUtils.getCurrentUserInfo();
		org.flowable.engine.repository.Model modelDb=modelService.getModel(model.getId());

		String modelBranchId=modelDb.getTenantId();
		if(!user.getBranchId().equals(modelBranchId)){
				return Result.error("tenant-id-not-platform-001", "该流程属于其它机构【%s】的流程模型，你无权取消该发布",modelBranchId);
			}

			if(LoginUtils.hasAnyRoles("superAdmin","flowAdmin","platformAdmin","branchAdmin")) {
				deploymentService.deleteModel(model.getId());
			}else{
				return Result.error("need-flowAdmin-or-platformAdmin", "该接口属于重大影响接口，需要流程管理员、平台管理员、机构管理员才能操作");
			};
			return Result.ok();
	}
}
